#include<queue>
#include<string>
using namespace std;
#define SIZE 5
class Task
{
public:
    Task()
    {
        ;
    }
    Task(int x,int y,char op)
    :_x(x)
    ,_y(y)
    ,_op(op)
    {
        ;
    }
    void operator()()
    {
        switch(_op)
        {
            case '+':
            {
                _result = _x + _y;
                _exitcode = 0;
            }
            break;
            case '-':
            {
                _result = _x - _y;
                _exitcode = 0;
            }
            break;
            case '*':
            {
                _result = _x * _y;
                _exitcode = 0;
            }
            break;
            case '/':
            {
                if(_y == 0)
                    _exitcode = 1;
                else 
                _result = _x / _y;
            }
                break;
             case '%':
            {   
                if(_y == 0)
                    _exitcode = 1;
                else    
                _result = _x % _y;
            }
            break;
        }
    }
    string getformat()
    {
        return  to_string(_x) + _op + to_string(_y)+'?';
    }
    string getRformat()
    {
        return to_string(_result) + "("+to_string(_exitcode) + ")";
    }
    int _x;
    int _y;
    char _op;
    int _result;
    int _exitcode = 0;
};
template<class T>
class BlockQueue
{
public:
    BlockQueue()
    {
        pthread_mutex_init(&mutex,nullptr);
        pthread_cond_init(&Productor,nullptr);
        pthread_cond_init(&Consumer,nullptr);
    }
    ~BlockQueue()
    {
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&Productor);
        pthread_cond_destroy(&Consumer);
    }
    bool isEmpty()
    {
        return q.size() == 0;
    }
    bool isFull()
    {
        return q.size() == SIZE;
    }
    void pop(T& data)
    {
        //加锁
        pthread_mutex_lock(&mutex);
        while(isEmpty())//若此时队列为空,之所以是while，是因为假如有多个线程被唤醒,此时队列又为空,然后就会继续pop出问题
        {
            pthread_cond_wait(&Consumer,&mutex);
        }
        data = q.front();
        q.pop();
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&Productor);
    }
    void push(const T& data)
    {
        pthread_mutex_lock(&mutex);
        while(isFull())//若此时队列为满,则不能继续push
        {
            pthread_cond_wait(&Productor,&mutex);
        }
        q.push(data);
        pthread_cond_signal(&Consumer);
        pthread_mutex_unlock(&mutex);
    }
private:
    std::queue<T> q;  
    pthread_mutex_t mutex;  
    pthread_cond_t Productor;
    pthread_cond_t Consumer;
};